package per.srp.demo.carLink.testP;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import per.srp.demo.carLink.Utils.CarInfoCodeTool;
import per.srp.demo.carLink.Utils.MyThread;
import per.srp.demo.carLink.Utils.SocketOperation;
import per.srp.demo.carLink.entity.Car;
import per.srp.demo.carLink.entity.CarCommand;

import java.io.IOException;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Queue;

public class CarClient {
    //默认最小速度单位
    private static double defaultV = 0.000001;

    private String CarNo;

    //默认位置
    private String carDefaultPosition = "{\"code\":\"1232223289\",\"no\":\"testCar\",\"lon\":86.064513,\"lat\":44.307681,\"v\":0.0,\"b\":0}";
    //默认位置发送命令
    private JSONObject defaultPosCommandPack = JSONObject.parseObject(carDefaultPosition);


    //小车命令队列
    private Queue<CarCommand> carCommandsQueue = new LinkedList<>();

    public CarClient(String CarNo){
        this.CarNo = CarNo;
        carDefaultPosition = "{\"code\":\"1232223289\",\"no\":\""+CarNo+"\",\"lon\":86.064513,\"lat\":44.307681,\"v\":0.0,\"b\":0}";
        //默认位置发送命令
        defaultPosCommandPack = JSONObject.parseObject(carDefaultPosition);
    }


    public void linkToServer() throws Exception {
        CarClient that = this;
        MyThread thread = new MyThread(true) {
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(1000);
                        String encodeJson = CarInfoCodeTool.enCodeJSONObject(defaultPosCommandPack);

                        //发送当前位置
                        Socket client = new Socket("127.0.0.1",9090);

                        //发送当前位置
                        SocketOperation.writeAndClose(client,encodeJson);

                        //接收服务端指令
                        String readStr = SocketOperation.read(client);
                        //解码转json
                        JSONObject deCodeReadStrJson = CarInfoCodeTool.deCodeToJSONObject(readStr);

                        System.out.println("----------"+that.CarNo+"-----------");
                        System.out.println(deCodeReadStrJson);
                        System.out.println(readStr);

                        //json转command
                        JSONArray commandArray = deCodeReadStrJson.getJSONArray("commands");

                        if(commandArray!=null){
                            //添加指令到队列
                            int size = commandArray.size();
                            for(int i=0;i<size;i++){
                                CarCommand currentCommand = commandArray.getObject(i,CarCommand.class);
                                //收到强制停止命令
                                if("forcebreak".equals(currentCommand.getCommand())){
                                    forceBreak();
                                    continue;
                                }
                                carCommandsQueue.add(currentCommand);
                            }
                        }

                        client.close();
                        System.out.println("over");
                    }catch (Exception e){

                    }
                }
            }
        };
    }



    //小车移动模拟
    public void move(double addLat,double addLng){
        double lat = defaultPosCommandPack.getDouble("lat")+addLat;
        double lng = defaultPosCommandPack.getDouble("lon")+addLng;
        defaultPosCommandPack.put("lat",lat);
        defaultPosCommandPack.put("lon",lng);
    }

    /**
     * 强制停止
     */

    boolean forceBreak = false;
    public void forceBreak(){
        forceBreak = true;
        carCommandsQueue.clear();
    }

    /**
     * 执行命令队列
     * @param command
     * @throws InterruptedException
     */
    public void doCommand(CarCommand command) throws InterruptedException {
        if(command==null) return;
        System.out.println("docommand: "+command.getCommand());
        int time = command.getTime();

        //循环时间： 即时间 * 速度
        for(int i=0;i<time;i++){
            //收到强制停止命令，结束当前执行
            if(forceBreak){
                forceBreak=false;
                break;
            }
            double value = defaultV*Double.valueOf(command.getOther());
            switch (command.getCommand()){
                case "up":{
                    //速度单位 * 速度
                    move(value,0);
                }break;
                case "down":{
                    move(-1.0*value,0);
                }break;
                case "left":{
                    move(0,-1.0*value);
                }break;
                case "right":{
                    move(0,1.0*value);
                }break;
                case "stop":{
                }break;
            }
            Thread.sleep(1000);
        }
    }

    /**
     * 读取命令队列，挨个执行
     */
    public void readCommand(){
        MyThread m = new MyThread(true) {
            @Override
            public void run() {
                while(true){
                    //弹出第一条命令
                    CarCommand currentCommand = carCommandsQueue.poll();
                    try {
                        doCommand(currentCommand);
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }


    public static void main(String[] args) throws Exception {
        CarClient carClient = new CarClient("testCar1");
        //读取服务端指令
        carClient.readCommand();
        //不断向服务器发送实时位置
        carClient.linkToServer();
//
//
//        CarClient carClient2 = new CarClient("testCar2");
//        //读取服务端指令
//        carClient2.readCommand();
//        //不断向服务器发送实时位置
//        carClient2.linkToServer();
//
        while (true){
            //阻塞主线程
            Thread.sleep(10*000);
        }

//        System.out.println("{\"code\":\"1232223289\",\"no\":\""+"1231232322"+"\",\"lon\":86.064513,\"lat\":44.307681,\"v\":0.0,\"b\":0}");
    }
}

